﻿namespace MhAdmin.System;

/// <summary>
/// <inheritdoc cref="IRulesService"/>
/// </summary>
public class RulesService : DbRepository<DevRules>, IRulesService
{
    private readonly ILogger<RulesService> _logger;
    private readonly ISysUserService _sysUserService;
    private readonly IRulesUtils _rule;

    public RulesService(ILogger<RulesService> logger, ISysUserService sysUserService, IRulesUtils rule)
    {
        _sysUserService = sysUserService;
        _logger = logger;
        _rule = rule;
    }

    #region 查询

    /// <inheritdoc/>
    public async Task<SqlSugarPagedList<DevRules>> Page(RulesPageInput input)
    {
        var query = await GetQuery(input);//获取查询条件
        var pageInfo = await query.ToPagedListAsync(input.Current, input.Size);//分页
        return pageInfo;
    }

    /// <inheritdoc/>
    public async Task<List<DevRules>> List(RulesPageInput input)
    {
        var query = await GetQuery(input);//获取查询条件
        var list = await query.ToListAsync();
        return list;
    }

    /// <inheritdoc />
    public async Task<DevRules> Detail(BaseIdInput input)
    {
        var rules = await GetFirstAsync(it => it.Id == input.Id);
        var errorMessage = $"您没有权限查看该数据";
        //获取数据范围
        var dataScope = await _sysUserService.GetLoginUserApiDataScope();
        if (dataScope != null && (!dataScope.Contains(rules.CreateOrgId) || rules.CreateUserId != UserManager.UserId))//判断机构ID是否在数据范围或者创建人是否为当前登录人
            throw Oops.Bah(errorMessage);
        return rules;
    }

    //外键查询

    #endregion 查询

    #region 新增

    /// <inheritdoc />
    public async Task Add(RulesAddInput input)
    {
        var rules = input.Adapt<DevRules>();//实体转换
        await CheckInput(rules);//检查参数
        await InsertAsync(rules);//插入数据
    }

    #endregion 新增

    #region 编辑

    /// <inheritdoc />
    public async Task Edit(RulesEditInput input)
    {
        var rules = input.Adapt<DevRules>();//实体转换
        await CheckInput(rules);//检查参数
        await UpdateAsync(rules);//更新数据
    }

    #endregion 编辑

    #region 删除

    /// <inheritdoc />
    public async Task Delete(List<BaseIdInput> input)
    {
        //获取所有ID
        var ids = input.Select(it => it.Id).ToList();
        if (ids.Count > 0)
        {
            //获取数据范围
            var dataScope = await _sysUserService.GetLoginUserApiDataScope();
            var ruless = await GetListAsync(it => ids.Contains(it.Id), it => new DevRules { CreateOrgId = it.CreateOrgId, CreateUserId = it.CreateUserId });//根据ID获取机构ID和创建者ID
            ruless.ForEach(it =>
            {
                if (dataScope != null && !dataScope.Contains(it.CreateOrgId) && it.CreateUserId != UserManager.UserId) throw Oops.Bah(ErrorCodeEnum.A0004);//如果不包含机构id并且不是自己创建的
            });
            await DeleteByIdsAsync(ids.Cast<object>().ToArray());//删除数据
        }
    }

    #endregion 删除

    #region 测试

    /// <inheritdoc />
    public async Task<List<string>> TestCode(RulesTestInput input)
    {
        List<string> codes = new();
        try
        {
            var generator = await _rule.NextArrayAsync(input.RuleCode, input.Length);
            while (generator.HasNext)
            {
                codes.Add(generator.Current);
            }
        }
        catch (RuleException ex)
        {
            throw Oops.Bah(ex.Message);
        }

        return codes;
    }

    #endregion 测试

    #region 方法

    /// <summary>
    /// 检查输入参数
    /// </summary>
    /// <param name="rules"></param>
    private async Task CheckInput(DevRules rules)
    {
        var errorMessage = $"您没有权限操作该数据";
        if (rules.Id == MhAdminConst.Zero)
        {
            //表示新增
            if (await IsAnyAsync(x => x.RuleCode == rules.RuleCode)) throw Oops.Bah("规则编码已存在");
        }
        else
        {
            //表示编辑
            if (await IsAnyAsync(x => x.RuleCode == rules.RuleCode && x.Id != rules.Id)) throw Oops.Bah("规则编码已存在");
        }
    }

    /// <summary>
    /// 获取Sqlsugar的ISugarQueryable
    /// </summary>
    /// <param name="input"></param>
    /// <returns></returns>
    private async Task<ISugarQueryable<DevRules>> GetQuery(RulesPageInput input)
    {
        //获取数据范围
        var dataScope = await _sysUserService.GetLoginUserApiDataScope();
        //动态查询条件,如果是连表查询,里面的it要改成连表里对应的别名
        var exp = Expressionable.Create<DevRules>();
        exp.AndIF(dataScope is { Count: > 0 }, it => dataScope.Contains(it.CreateOrgId));//用户机构在数据范围内
        exp.AndIF(dataScope is { Count: 0 }, it => it.CreateUserId == UserManager.UserId);//默认创建者ID等于自己,根据实际情况修改条件
        var query = Context.Queryable<DevRules>()
                         .WhereIF(!string.IsNullOrWhiteSpace(input.RuleName), it => it.RuleName.Contains(input.RuleName.Trim()))
                         .WhereIF(!string.IsNullOrWhiteSpace(input.RuleCode), it => it.RuleCode.Contains(input.RuleCode.Trim()))
                         .WhereIF(!string.IsNullOrWhiteSpace(input.RuleClass), it => it.RuleClass.Contains(input.RuleClass.Trim()))
                         .WhereIF(!string.IsNullOrWhiteSpace(input.Header), it => it.Header.Contains(input.Header.Trim()))
                         .Where(exp.ToExpression())
                         .OrderByDescending(x => x.CreateTime);
        return query;
    }

    /// <inheritdoc/>
    public async Task<List<RulesImportInput>> CheckImport<RulesImportInput>(List<RulesImportInput> data, bool clearError = false)
    {
        return data;
    }

    #endregion 方法
}
